package project.movieMap.baseLib.serializationStuff;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.ArrayType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class DefaultSerializerImpl implements Serializer {
    private final ObjectMapper mapper;

    public DefaultSerializerImpl() {
        mapper = new ObjectMapper();
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    }

    @Override
    public <T> String toJson(T object) {
        try {
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException ex) {
            String cause = String.format("Object %s cannot be serialized to json", object.toString());
            RuntimeException reThrow = new RuntimeException(cause);
            reThrow.addSuppressed(ex);
            throw reThrow;
        }
    }

    @Override
    public <T> T instanceOf(String jsonString)
            throws ClassNotFoundException, IOException {
        JsonNode root = mapper.readTree(jsonString);
        JsonNode classNode = root.path("@class");
        String className = classNode.asText();
        @SuppressWarnings("unchecked")
        T ret = (T) mapper.readValue(jsonString, Class.forName(className));
        return ret;
    }
}
